package com.jc.common.util;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

/***
 * 图片压缩处理工具类
 * @author zyf
 *
 */
public class ImageUtil {
	
	 /***
	  *      压缩图片 宽高至指定的大小, 如果图片宽高比例,和传入的 宽度，高度比例不一致，则按最长的边进行压缩，等比缩放。
	  * @param sourceFullPath : 原图片全路径
	  * @param width :   宽度 像素
	  * @param height :  高度 像素
	  * @param toFullPath : 输出全路径（包含图片名称）
	  * @throws Exception : 压缩异常
	  */
	 private static void size(String sourceFullPath,int width,int height ,String toFullPath) throws Exception {
        try {
            Thumbnails.of(sourceFullPath).size(width,height).toFile(toFullPath);
        } catch (IOException e) {
            throw e;
        }
	 }
	 
	 public static void retateImage(String sourceFullPath,int readings,String toFullPath) throws Exception {
		try {
	            Thumbnails.of(sourceFullPath).
	                    rotate(readings).
	                    toFile(toFullPath);
	    } catch (IOException e) {
	            throw e;
	    }
	 }
	 
	 /***
	  *  该函数不进行分辨率压缩 ,最多压缩三次
	  * @param sourceFullPath
	  * @param readings
	  * @param toFullPath
	  * @param targetSizeKB
	  * @throws Exception
	  */
	 public static String outputQuality(String sourceFullPath,double readings,String toFullPath,BigDecimal targetSizeKB) throws Exception {
		 try {
			 Thumbnails.of(sourceFullPath).scale(1F).outputQuality(0.1).toFile(toFullPath);
	         BigDecimal imageSize = getFileSize(toFullPath);
	   		 if(imageSize.compareTo(targetSizeKB) >= 0) {	//压缩后大小还是比要求的文件大小大，则再次压缩	 
		   			//create new file name 
	   			    String fname = toFullPath.substring(toFullPath.lastIndexOf("\\")+1, toFullPath.lastIndexOf(".")) + 1;
	   			    String extName = FileUtil.getFileExtName(toFullPath);	   			    
	   			    String newFullFilePath = toFullPath.substring(0,toFullPath.lastIndexOf("\\")+1) + fname + "." + extName;
	   			    Thumbnails.of(toFullPath).scale(1F).outputQuality(readings).toFile(newFullFilePath);
	   			    File fs = new File(toFullPath);
	   			    if(fs.exists() && fs.isFile()) {
	   			    	fs.delete();
	   			    }
	   			    	   			    
	   			    if(getFileSize(newFullFilePath).compareTo(targetSizeKB) >= 0) {
	   			    	String fname1 = newFullFilePath.substring(newFullFilePath.lastIndexOf("\\")+1, newFullFilePath.lastIndexOf(".")) + 1;
		   			    String extName1 = FileUtil.getFileExtName(newFullFilePath);	   			    
		   			    String newFullFilePath1 = newFullFilePath.substring(0,newFullFilePath.lastIndexOf("\\")+1) + fname1 + "." + extName1;
		   			    Thumbnails.of(newFullFilePath).scale(1F).outputQuality(readings).toFile(newFullFilePath1);
		   			    File fs1 = new File(newFullFilePath);
		   			    if(fs1.exists() && fs1.isFile()) {
		   			    	fs1.delete();
		   			    }	
		   			    return newFullFilePath1;
	   			    }else {
	   			    	return newFullFilePath;
	   			    }	   			 
	   		 }else {
	   			 return toFullPath;
	   		 }
	    } catch (IOException e) {
	            throw e;
	    }
	 }
	 
	 
	 
	 public static void outputQuality(String sourceFullPath,double readings,String toFullPath) throws Exception {
		 try {
	            Thumbnails.of(sourceFullPath).scale(1F).outputQuality(readings).toFile(toFullPath);
	    } catch (IOException e) {
	            throw e;
	    }
	 }
	 
	 
	 /***
	     *     压缩图片体积
	  * @param sourceFullPath 原图片全路径
	  * @param readings 大小压缩比例
	  * @param width 宽度 像素
	  * @param height 高度 像素
	  * @param toFullPath 输出全路径（包含图片名称）
	  * @throws Exception 压缩异常
	  */
	 public static void outputQuality(String sourceFullPath,double readings,int width,int height,String toFullPath) throws Exception {
		 try {
	            Thumbnails.of(sourceFullPath).size(width, height).outputQuality(readings).toFile(toFullPath);
	    } catch (IOException e) {
	            throw e;
	    }
	 }
	 /***
	  *     压缩图片体积压缩到小于等于指定大小 , 最多压缩三次
	  * @param targetSizeKB 压缩目标大小 单位：KB 
	  * @param sourceFullPath 原图片全路径
	  * @param readings 大小压缩比例
	  * @param width 宽度 像素
	  * @param height 高度 像素
	  * @param toFullPath 输出全路径（包含图片名称）
	  * @throws Exception 压缩异常
	  */
	 public static String outputQualityX(String sourceFullPath,BigDecimal targetSizeKB,int width,int height,String toFullPath) throws Exception {
		
		 outputQuality(sourceFullPath,0.4,width,height,toFullPath);
		 BigDecimal imageSize = getFileSize(toFullPath);
		 
		 if(imageSize.compareTo(targetSizeKB) >= 0) {	//压缩后大小还是比要求的文件大小大，则再次压缩	 
	   			//create new file name 
			    String fname = toFullPath.substring(toFullPath.lastIndexOf("\\")+1, toFullPath.lastIndexOf(".")) + 1;
			    String extName = FileUtil.getFileExtName(toFullPath);	   			    
			    String newFullFilePath = toFullPath.substring(0,toFullPath.lastIndexOf("\\")+1) + fname + "." + extName;
			    
			    outputQuality(toFullPath,0.4,width,height,newFullFilePath);
			    File fs = new File(toFullPath);
			    if(fs.exists() && fs.isFile()) {
			    	fs.delete();
			    }
			    
			    
			    if(getFileSize(newFullFilePath).compareTo(targetSizeKB) >= 0) {
			    	String fname1 = newFullFilePath.substring(newFullFilePath.lastIndexOf("\\")+1, newFullFilePath.lastIndexOf(".")) + 1;
	   			    String extName1 = FileUtil.getFileExtName(newFullFilePath);	   			    
	   			    String newFullFilePath1 = newFullFilePath.substring(0,newFullFilePath.lastIndexOf("\\")+1) + fname1 + "." + extName1;
	   			    outputQuality(newFullFilePath,0.4,width,height,newFullFilePath1);	   			 
	   			    File fs1 = new File(newFullFilePath);
	   			    if(fs1.exists() && fs1.isFile()) {
	   			    	fs1.delete();
	   			    }	
	   			    return newFullFilePath1;
			    }else {
			    	return newFullFilePath;
			    }
			    
			    
		 }else {
			 return toFullPath;
		 }
		 
		 
		 
		 
		 
		 
		 
		
//		 if(imageSize.compareTo(targetSizeKB) == -1) {		 
//			 size(sourceFullPath,width,height,toFullPath);			 
//		 }else {
//			 size(sourceFullPath,width,height,toFullPath);	
//			 while( getFileSize(toFullPath).compareTo(targetSizeKB) == 1) {
//				 size(sourceFullPath,width,height,toFullPath);
//			 }
//			 
//		 }
	 }
	 
	 private static void generateRotationWatermark() throws Exception {
	        try {
	            Thumbnails.of("data/2016010208.jpg").
	                    size(160,160). // 缩放大小
	                    rotate(90). // 顺时针旋转90度
	                    watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("data/newmeinv.jpg")),0.5f). //水印位于右下角,半透明
	                    outputQuality(0.8). // 图片压缩80%质量
	                    toFile("data/2016010208_new.jpg");
	        } catch (IOException e) {
	            throw e;
	        }
	    }
	 
	 /***
	  * 得到文件大小,以KB为单位
	  * @param sourceFullPath
	  * @return
	  * @throws Exception
	  */
	 public static BigDecimal getFileSize(String sourceFullPath) throws Exception{
		 try {
			 File _f = new File(sourceFullPath);
			 if(!_f.isFile()) {
				 throw new Exception(sourceFullPath + " 不是一个有效的文件路径,或文件不存在, 无法获取大小. ");
			 }
			 BigDecimal bd = BigDecimal.valueOf(_f.length());
			 return bd.divide(BigDecimal.valueOf(1024),0,RoundingMode.HALF_UP);
		 }catch(Exception e) {
			 throw e;
		 }		 
	 }
	 
	 
	 
	 public static void main(String[] args) {
		try {
			//outputQuality("e://111.png",0.5,800,800,"e://222.png");
			//outputQuality("e://111.png",0.7,"e://333888.png");
			
			
			
			
			//System.out.println(getFileSize("e://111.png").toString());;
			
			//outputQualityX("e://111.png", BigDecimal.valueOf(500L),600,600,"e://5333255.png");
			
			//outputQuality("H:\\新建文件夹11\\同仁堂\\01冬虫夏草-冬虫夏草-40-4克\\详情页.jpg", 0.4, "e:\\222.jpg");
			
			//outputQuality("e:\\222.jpg",0.1,"e:\\5555.jpg");
			
			outputQuality("D:\\1111.png",0.1,"e:\\888888888.png",BigDecimal.valueOf(100L));
			
			
			
			//downloadPicture("http://img.test.jioao.cn/images/uploadImgForm/201711141437166411.png","E://淀山湖2018秋收新大米松早香１号5kg（10斤）软糯香米道甜贡米/DD.png");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	 
	
	    public static void downloadPicture(String remoteUrl,String localPath) throws Exception {
	        URL url = null;        
	        try {
	            url = new URL(remoteUrl);
	            DataInputStream dataInputStream = new DataInputStream(url.openStream());
	            System.out.println(localPath);
	            if(localPath == null || localPath.length() == 0) {
	            	throw new Exception("下载错误,图片保存路径未传入");
	            }
	            FileOutputStream fileOutputStream = new FileOutputStream(new File(localPath));
	            ByteArrayOutputStream output = new ByteArrayOutputStream();
	            byte[] buffer = new byte[1024];
	            int length;
	            while ((length = dataInputStream.read(buffer)) > 0) {
	                output.write(buffer, 0, length);
	            }
	            fileOutputStream.write(output.toByteArray());
	            dataInputStream.close();
	            fileOutputStream.close();
	        } catch (MalformedURLException e) {
	        	e.printStackTrace();
	            throw e;
	        } catch (IOException e) {
	        	e.printStackTrace();
	            throw e;
	        }
	    }
	 
	 
	 
	 
}
